package plgbase

import (
	"dgo/MyProj/PrjHttpUtils"
	"dgo/goutils/utils"
	"fmt"
	"gitee.com/ymofen/supervalue"
	"time"
)

/*
*

 1. 收到的reqPlg插件 request请求

 2. 调用impl插件去完成

 3. 再通过respPlg插件响应回去

    reqPlg.onRequest->implPlg.DoRequest->respPlg.Disp()
*/
type RequestFromExPlg struct {
	PlgBase
	reqPlg  *InnerEx
	respPlg *InnerEx
	implPlg *InnerPlug
	msglst  *utils.SyncCycleList
}

/*
收到ex的请求, 进行异步
*/
func (this *RequestFromExPlg) onRequest(sender interface{}, channelid string, subscribeid interface{}, data interface{}, tag interface{}, isBreak *bool) bool {
	if data != nil {
		json, _ := wrapper.NewSVFrom(data, false)
		if json == nil {
			this.LogWarnMessage("[非法数据]:接收到非法的数据:%+v", data)
			return true
		}

		uuid := json.StringByName("__request_uuid", "")
		if len(uuid) == 0 {
			this.LogWarnMessage("[非法数据]:接收到非法的数据:%+v", json.String())
			return true
		}
		utils.DefaultWorkers().PostTaskFunc(uuid, func() { // 异步请求, 避免死锁
			json.RemoveKey("__request_uuid")
			rval := this.implPlg.DoRequest(json)
			if err, ok := rval.(error); ok {
				resp := wrapper.NewSVObject()
				resp.SetKeyValue("__resp_raw_err", err.Error())
				resp.SetKeyValue("__request_uuid", uuid)
				this.respPlg.DispatchData("", this, resp, nil)
			} else {
				resp, _ := wrapper.NewSVFrom(rval, false)
				if resp == nil {
					this.LogWarnMessage("[非法数据]:接收到非法的数据:%+v", rval)
					return
				}
				resp.SetKeyValue("__request_uuid", uuid)
				this.respPlg.DispatchData("", this, resp, nil)
			}
		})

	}
	return true
}

/*
*

	{
	  "id": "sjyt-ex",
	  "type": "plg.request.from.ex",
	  "conf": {
	      "req-plg":{"id":"mqtt", "topic":"/sjyt/request"},
	      "resp-plg":{"id":"mqtt", "topic":"/sjyt/response"},
	      "impl-plg":"xxx",
	  }
	}
*/
func (this *RequestFromExPlg) ReloadConf(conf *wrapper.SuperValue) error {
	if conf == nil {
		return nil
	}

	if this.reqPlg == nil {
		this.reqPlg = NewInnerEx()
	}
	this.reqPlg.ReloadConfAndSubscribe(conf.ValueByName("req-plg"), this.onRequest)

	if this.respPlg == nil {
		this.respPlg = NewInnerEx()
	}
	this.respPlg.ReloadConf(conf.ValueByName("resp-plg"))

	if this.implPlg == nil {
		this.implPlg = NewInnerPlug2(this)
	}
	this.implPlg.ReloadConf(conf.ValueByName("impl-plg"))

	if this.msglst == nil {
		this.msglst = utils.NewSyncCycleList()
	}

	utils.DefaultPatrolTask().AddTask(this, time.Second*30, func(id interface{}, args ...interface{}) {
		//utils.DefaultWorkers().PostTaskFunc(this, this.innerWork)
	})
	return nil
}

func (this *RequestFromExPlg) Close() (err error) {
	this.PlgBase.Close()
	utils.DefaultPatrolTask().DelTask(this)
	return
}

func (this *RequestFromExPlg) OnRequestStatus(args ...interface{}) (resp interface{}) {
	req := wrapper.GetSVFromArgs(args, 0)
	if req == nil {
		return fmt.Errorf("非法的参数")
	}

	itype := req.IntByName("type", 0)
	if itype == 99 {
		json := wrapper.NewSVObject()
		json.SetKeyValues("now", utils.NowString())
		return resp
	} else if itype == 98 {
		return this.msglst
	} else if itype == 1 {
		json := wrapper.NewSVArray()
		//searchval := req.StringByName("searchval", "")
		//sn := 0
		//maxn := req.IntByName("n", 100)
		//this.lst.ListRangeV2(func(key, val interface{}) bool {
		//	pojo := val.(*VrsSitePojo)
		//	ok := true
		//	if len(searchval) > 0 {
		//		ok = strings.Contains(pojo.id, searchval)
		//	}
		//	return ok
		//}, func(k0, v0, k1, v1 interface{}) bool {
		//	p0 := v0.(*VrsSitePojo)
		//	p1 := v1.(*VrsSitePojo)
		//	return p0.id < p1.id
		//}, func(key, val interface{}) bool {
		//	sn++
		//	pojo := val.(*VrsSitePojo)
		//	itm := json.AppendObject()
		//	itm.SetKeyValue("sn", sn)
		//	itm.SetKeyValue("id", pojo.id)
		//	return sn < maxn
		//})

		return json
	} else {
		var sb utils.BytesBuilder
		PrjHttpUtils.AppendIndexBody(&sb, "status", "status?type=99")
		PrjHttpUtils.AppendIndexBody(&sb, "msglist", "status?type=98&n=100&searchval=")
		PrjHttpUtils.AppendIndexBody(&sb, "lst", "status?type=1&n=100&searchval=")
		return sb.Bytes()
	}
}

func (this *RequestFromExPlg) LogInfoMessage(s string, args ...interface{}) {
	this.msglst.LogMsg(s, args...)
	utils.Log.Msgf(this.PlugId, utils.LogLV_INFO, 1, s, args...)
}

func (this *RequestFromExPlg) LogWarnMessage(s string, args ...interface{}) {
	this.msglst.LogMsg(s, args...)
	utils.Log.Msgf(this.PlugId, utils.LogLV_WARN, 1, s, args...)
}

func CreateRequestFromExPlgFunc(args ...interface{}) (rval interface{}, err error) {
	obj := &RequestFromExPlg{}

	if len(args) > 0 {
		if str, ok := args[0].(string); ok {
			obj.PlugId = str
		}
	}
	rval = obj
	return
}
